package com.foodev.maven.gwt;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

public abstract class AbstractGwtScriptMojo extends AbstractGwtMojo {


  /**
   * Creates a new executable script under the <code>gwtHome</code>.
   * @param name the name of the script without the ending .sh or .bat which
   * will be added depending on OS.
   * @return the newly created file.
   * @throws IOException
   */
  protected File createScriptFile(String name) throws IOException {

    if ( !gwtHome.exists() ) gwtHome.mkdirs();
    
    File f = new File(gwtHome, name + (isWindows() ? ".bat" : ".sh"));

    if (f.exists())
      f.delete();

    f.createNewFile();

    if (isWindows()) {
      // no +x in windows
    } else {
      
      try {
        ProcessBuilder pb = new ProcessBuilder(new String[] { "chmod", "a+x",
            f.getAbsolutePath() });
        Process proc = pb.start();
        proc.waitFor();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
      
    }

    return f;

  }


  /**
   * Writes the script header which for unix is <code>#!/bin/sh</code> or
   * <code>#!/usr/bin/sh</code> and nothing for windows.
   * @param writer the writer to write to
   * @throws IOException
   */
  protected void startScript( PrintWriter writer ) throws IOException {
    
    if ( isWindows() ) {

      writer.println( "@ECHO OFF" );

    } else {
      
      File sh = new File("/bin/sh" );
      if ( !sh.exists() ) {
        sh = new File( "/usr/bin/sh" );
      }
      
      writer.println("#!"+sh.getAbsolutePath());
      
    }
    
  }
  
  
  /**
   * Writes the given list of strings as a classpath to the given
   * writer.
   * @param writer The writer to write to
   * @param classpath The classpath as elements in a list of strings.
   * @throws IOException
   */
  protected void writeClasspath( PrintWriter writer, List<String> classpath ) 
    throws IOException { 
    
    StringBuilder buf = new StringBuilder();
    
    if ( isWindows() ) {
      buf.append("set CLASSPATH=");
    } else {
      buf.append("export CLASSPATH=");
    }
    for ( Iterator<String> iter = classpath.iterator(); iter.hasNext(); ) {
      buf.append("\""+iter.next()+"\""+File.pathSeparator);
      // break if line is longer than 4000
      if ( buf.length() > 4000 && iter.hasNext() ) { 
        buf.deleteCharAt(buf.length()-1); // last ':'
        writer.println(buf.toString());
        buf = new StringBuilder();
        if ( isWindows() ) {
          buf.append("set CLASSPATH=%CLASSPATH%;");
        } else {
          buf.append("CLASSPATH=\"$CLASSPATH\":");
        }
      }
    }
    buf.deleteCharAt(buf.length()-1); // last ':'
    writer.println(buf.toString());

  }
  
  
}
